home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / cd_mci.exe / CD.CPP < prev    next >
C/C++ Source or Header  |  1993-01-07  |  14KB  |  611 lines

  1.  
  2. #include <windows.h>
  3. #include <windowsx.h>
  4. #include <mmsystem.h>
  5. #include <toolhelp.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8.  
  9. #include "mci.h"
  10. #include "cd.h"
  11.  
  12. #define TIME_NONE          -999999
  13. #define INI_NAME           "cdplay.ini"
  14. #define INI_TOPIC_NAME     "Names"
  15. #define INI_TOPIC_SETTINGS "Settings"
  16. #define INI_POSITION       "Position"
  17. #define MAX_CDNAME         64
  18.  
  19. HINSTANCE hInst;
  20. char szAppName[] = "CD Player";
  21. BOOL CALLBACK CdDlgProc(HWND hwnd, UINT message,
  22.                         WPARAM wParam, LPARAM lParam);
  23. BOOL CALLBACK TitleDlgProc(HWND hwnd, UINT message,
  24.                            WPARAM wParam, LPARAM lParam);
  25.  
  26. enum CDMode { ModeNotReady, ModePause, ModePlaying, ModeStop, ModeScanning };
  27.  
  28. class CDPlayer : public CDAudio {
  29.    HWND hwnd;
  30.    int nTracks;
  31.    DWORD *PosTracks;    // Positionen der einzelnen Tracks in Millisekunden
  32.    DWORD *LenTracks;    // LΣngen der einzelnen Tracks in Millisekunden
  33.    int Track;           // aktueller Track
  34.    DWORD Sync;          // Systemzeit, bei dem das nΣchste "Sync" stattfindet
  35.    DWORD StartTime;     // Systemzeit, bei dem die CD gestartet wurde
  36.    CDMode mode;         // current status of drive
  37.    DWORD dwPosition;    // always contains the disc position in ms
  38.    WORD wTimer;         // ID of timer used to update display
  39.    char CDTitle[MAX_CDNAME];  // Titel der CD
  40.    char CDID[10];             // ID-String der CD
  41.    BOOL bCountUp;             // count seconds up or down
  42.  
  43. protected:
  44.    DWORD Time();
  45.    int Synchronize(DWORD time = 0);
  46.    void DisplayTime(LONG time, WORD wID);
  47.    void UpdateDisplay(DWORD wTime);
  48.    void CheckReady();
  49.    void SetTrack(int wTrack);
  50.    void SetPosition(DWORD dwPos);
  51.  
  52. public:
  53.    int Timer();
  54.    int Login();          // Betimmt LΣnge der Tracks etc.
  55.    int Logout();         // Setzt die Parameter zurⁿck
  56.    int Resync();
  57.    int Forward();
  58.    int Back();
  59.    int Pause();
  60.    int Play();
  61.    int Stop();
  62.    void ToggleUp();
  63.    void EditTitle();
  64.    CDPlayer(HWND aWindow);
  65.    ~CDPlayer();
  66. };
  67.  
  68.  
  69. char *String(UINT id)
  70. {
  71.    static char szString[128];
  72.  
  73.    if (LoadString(hInst, id, szString, sizeof szString))
  74.       return szString;
  75.    else
  76.       return "";
  77. }
  78.  
  79.  
  80. DWORD MciError(HWND hwnd, DWORD d)
  81. {
  82.    char s[256];
  83.  
  84.    if (d) {
  85.       mciGetErrorString(d, s, sizeof s);
  86.       MessageBox(hwnd, s, szAppName, MB_OK);
  87.    }
  88.     return d;
  89. }
  90.  
  91.  
  92. CDPlayer::CDPlayer(HWND aWindow) : CDAudio(aWindow)
  93. {
  94.    nTracks = 0;
  95.    LenTracks = NULL;
  96.    mode = ModeNotReady;
  97.    Track = 0;
  98.    hwnd = aWindow;
  99.    Sync = 0;
  100.    dwPosition = 0;
  101.    bCountUp = TRUE;
  102.    wTimer = SetTimer(hwnd, 1, 1000, NULL);
  103. }
  104.  
  105.  
  106. CDPlayer::~CDPlayer()
  107. {
  108.    if (wTimer)
  109.       KillTimer(hwnd, 1);
  110. }
  111.  
  112.  
  113. DWORD CDPlayer::Time()
  114. {
  115.    return GetTickCount();
  116. /*
  117.    TIMERINFO ti;
  118.  
  119.    ti.dwSize = sizeof ti;
  120.    TimerCount(&ti);
  121.    return ti.dwmsSinceStart;
  122. */
  123. }
  124.  
  125.  
  126. int CDPlayer::Synchronize(DWORD time)
  127. {
  128.    int t;
  129.    BOOL bPlay;
  130.  
  131.    if (time == 0)
  132.       time = Time();
  133.  
  134.    Sync = time + 5000;
  135.  
  136.    SetTimeFormat(MCI_FORMAT_MILLISECONDS);
  137.    bPlay = Mode() == MCI_MODE_PLAY;
  138.  
  139.    if (mode == ModeNotReady) {
  140.       dwPosition = 0;
  141.       Track = 0;
  142.    }
  143.  
  144.    if (mode == ModePlaying && !bPlay) {
  145.       // CD has stopped
  146.       dwPosition = PosTracks[1];
  147.       Track = 0;
  148.       mode = ModeStop;
  149.    }
  150.    if (bPlay)
  151.       mode = ModePlaying;
  152.  
  153.    if (mode == ModePlaying) {
  154.       dwPosition = Position();
  155.       Track = CurrentTrack();
  156.       StartTime = time - dwPosition;
  157.       if (Sync > StartTime + PosTracks[Track] + LenTracks[Track])
  158.          Sync = StartTime + PosTracks[Track] + LenTracks[Track];
  159.    }
  160.    return TRUE;
  161. }
  162.  
  163.  
  164. void CDPlayer::DisplayTime(LONG time, WORD wID)
  165. {
  166.    char buff[20];
  167.    char buff2[20];
  168.  
  169.    if (time == TIME_NONE) {
  170.       SetDlgItemText(hwnd, wID, " --:--");
  171.       return;
  172.    }
  173.  
  174.    if (time >= 0) {
  175.       time /= 1000;
  176.       wsprintf(buff, " %02d:%02d", int(time / 60), int(time % 60));
  177.    } else {
  178.       time = -(time / 1000) + 1;
  179.       wsprintf(buff, "-%02d:%02d", int(time / 60), int(time % 60));
  180.    }
  181.    GetDlgItemText(hwnd, wID, buff2, sizeof buff2);
  182.    if (strcmp(buff, buff2))
  183.       SetDlgItemText(hwnd, wID, buff);
  184. }
  185.  
  186.  
  187. void CDPlayer::CheckReady()
  188. {
  189.    BOOL bReady = Ready();
  190.  
  191.    if (bReady && mode == ModeNotReady) {
  192.       // CD-Laufwerk ist gerade Ready geworden
  193.       HCURSOR hOldCur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  194.       mode = ModeScanning;
  195.       UpdateDisplay(dwPosition);
  196.       Login();
  197.       SetCursor(hOldCur);
  198.       mode = ModeStop;
  199.       Sync = 0;
  200.    }
  201.  
  202.    if (!bReady && mode != ModeNotReady ) {
  203.       // Laufwerk wurde gerade "gest÷rt"
  204.       Logout();
  205.       mode = ModeNotReady;
  206.       Sync = 0;
  207.    }
  208. }
  209.  
  210.  
  211. int CDPlayer::Resync()
  212. {
  213.    CheckReady();
  214.    Synchronize();
  215.    UpdateDisplay(dwPosition);
  216.    if (wTimer)
  217.       KillTimer(hwnd, 1);
  218.    wTimer = SetTimer(hwnd, 1, 1000, NULL);
  219.    return TRUE;
  220. }
  221.  
  222.  
  223. void CDPlayer::UpdateDisplay(DWORD dwTime)
  224. {
  225.    static char buff[MAX_CDNAME];
  226.    char *s;    // title string to display
  227.    int t;      // track number to display
  228.    static UINT modes[] = {
  229.       IDS_NOTREADY,
  230.       IDS_PAUSED,
  231.       IDS_PLAYING,
  232.       IDS_STOPPED,
  233.       IDS_SCANNING
  234.    };
  235.  
  236.    t = Track;
  237.    s = *CDTitle ? CDTitle : String(modes[mode]);
  238.    if (mode == ModeNotReady || mode == ModeScanning) {
  239.       t = 0;
  240.       s = String(modes[mode]);
  241.       DisplayTime(TIME_NONE, ID_SINGLETIME);
  242.       DisplayTime(TIME_NONE, ID_TOTALTIME);
  243.    } else if (Track == 0) {
  244.       t = nTracks;
  245.       DisplayTime(0, ID_SINGLETIME);
  246.       DisplayTime(PosTracks[nTracks+1], ID_TOTALTIME);
  247.    } else {
  248.       if (bCountUp) {
  249.          DisplayTime(dwTime - PosTracks[Track], ID_SINGLETIME);
  250.          DisplayTime(dwTime - PosTracks[1], ID_TOTALTIME);
  251.       } else {
  252.          DisplayTime(PosTracks[Track+1] - dwTime, ID_SINGLETIME);
  253.          DisplayTime(PosTracks[nTracks+1] - dwTime, ID_TOTALTIME);
  254.       }
  255.    }
  256.  
  257.    if (GetDlgItemInt(hwnd, ID_TRACKCOUNT, NULL, FALSE) != t)
  258.       SetDlgItemInt(hwnd, ID_TRACKCOUNT, t, FALSE);
  259.  
  260.    GetDlgItemText(hwnd, ID_TITLE, buff, sizeof(buff));
  261.    if (strcmp(s, buff))
  262.       SetDlgItemText(hwnd, ID_TITLE, s);
  263. }
  264.  
  265.  
  266. int CDPlayer::Timer()
  267. {
  268.    CheckReady();
  269.  
  270.    DWORD dwTime = Time();
  271.    if (dwTime >= Sync) {
  272.       // Synchronisation required
  273.       Synchronize(dwTime);
  274.    }
  275.  
  276.    if (mode == ModePlaying)
  277.       dwPosition = dwTime - StartTime;
  278.    UpdateDisplay(dwPosition);
  279.    return TRUE;
  280. }
  281.  
  282.  
  283. void CDPlayer::SetTrack(int aTrack)
  284. {
  285.    Track = aTrack;
  286.    SetPosition(PosTracks[Track]);
  287. }
  288.  
  289.  
  290. void CDPlayer::SetPosition(DWORD dwPos)
  291. {
  292.    dwPosition = dwPos;
  293.    if (mode == ModePlaying) {
  294.       SetTimeFormat(MCI_FORMAT_MILLISECONDS);
  295.       MciError(hwnd, CDAudio::Play(MCI_FROM, dwPosition));
  296.    }
  297.    Resync();
  298. }
  299.  
  300.  
  301.  
  302. int CDPlayer::Forward()
  303. {
  304.    int w = Track + 1;
  305.    if (w > nTracks)
  306.       return TRUE;
  307.    SetTrack(w);
  308.    return TRUE;
  309. }
  310.  
  311.  
  312. int CDPlayer::Back()
  313. {
  314.    int w = Track - 1;
  315.    if (w < 1)
  316.       return TRUE;
  317.    SetTrack(w);
  318.    return TRUE;
  319. }
  320.  
  321.  
  322. int CDPlayer::Pause()
  323. {
  324.    if (mode == ModePlaying) {
  325.       SetTimeFormat(MCI_FORMAT_MILLISECONDS);
  326.       dwPosition = Position();
  327.       CDAudio::Stop();
  328.    }
  329.    mode = ModePause;
  330.    Resync();
  331.    return TRUE;
  332. }
  333.  
  334.  
  335. int CDPlayer::Play()
  336. {
  337.    if (mode == ModePlaying) {
  338.       // if playing, play restarts the current song
  339.       dwPosition = PosTracks[Track]; 
  340.    }
  341.    SetTimeFormat(MCI_FORMAT_MILLISECONDS);
  342.    MciError(hwnd, CDAudio::Play(MCI_FROM, dwPosition));
  343.    Resync();
  344.    return TRUE;
  345. }
  346.  
  347.  
  348. int CDPlayer::Stop()
  349. {
  350.    CDAudio::Stop();
  351.    mode = ModeStop;
  352.    SetTrack(0);
  353.    return TRUE;
  354. }
  355.  
  356.  
  357.  
  358. int CDPlayer::Logout()
  359. {
  360.    EnableWindow(GetDlgItem(hwnd, ID_EDIT), FALSE);
  361.    if (LenTracks) {
  362.       delete LenTracks;
  363.       delete PosTracks;
  364.       LenTracks = NULL;
  365.    }
  366.    nTracks = 0;
  367.    Track = 0;
  368.    *CDTitle = '\0';
  369.    return TRUE;
  370. }
  371.  
  372.  
  373. int CDPlayer::Login()
  374. {
  375.    int i;
  376.  
  377.    Logout();
  378.    if (!Ready())
  379.       return FALSE;
  380.  
  381.    nTracks = NumberO